﻿function Condition(interest, datefrom, dateto, period) {
    this.Interest = interest;
    this.Datefrom = datefrom;
    this.Dateto = dateto;
    this.Period = period;
}

function Conditional(divtablename) {

    this.Conditions = [];
    this.divTableName = divtablename;
    this.ConditonTable = undefined;
    this.conditionColumns = [
                { "mData": "Interest", "sTitle": "ดอกเบี้ย" },
                { "mData": "Period", "sTitle": "ระยะเวลาดอกเบี้ย" },
                {
                    "mData": "Datefrom", "sTitle": "เริ่ม", "fnRender": function (oObj) {
                        var javascriptDate = dateReviver(oObj.aData.Datefrom);
                        javascriptDate = (javascriptDate.getMonth() + 1) + "/" + javascriptDate.getDate() + "/" + javascriptDate.getFullYear();
                        return javascriptDate;
                    }
                },
                {
                    "mData": "Dateto", "sTitle": "ถึง", "fnRender": function (oObj) {
                        var javascriptDate = dateReviver(oObj.aData.Dateto);
                        javascriptDate = (javascriptDate.getMonth() + 1) + "/" + javascriptDate.getDate() + "/" + javascriptDate.getFullYear();
                        return javascriptDate;
                    }
                },
                {
                    "mData": null, "sTitle": "แก้ไข", "fnRender": function (oObj) {

                        return '<a class="edit" href="">Edit</a>';
                    }
                }
    ];
    this.AddCondition = function (i, s, e, p) {
        var conditon = new Condition(i,
            new Date(s),
            new Date(e),
            p);
        this.Conditions.push(conditon);
        //if (this.ConditonTable != undefined) {
        //    $('#' + this.divTableName).dataTable().fnAddData([conditon]);
        //} else {
        //    this.PopulateConditionTable();
        //}
    };
    this.SetConditionDate = function (d) {
        var date = d;
        $.each(this.Conditions, function (i, o) {
            o.Datefrom = new Date(date);
            o.Dateto = new Date(date).addMonths(parseInt(o.Period));
            date.addMonths(parseInt(o.Period));
        });
    };
    this.ClearCondition = function () {
        this.Conditions = [];
        this.PopulateConditionTable();
    };
    this.GetCondition = function () {
        return this.Conditions;
    };

    this.PopulateConditionTable = function () {
        this.ConditonTable = $('#' + this.divTableName).dataTable({
            "bPaginate": false,
            "bFilter": false,
            "bInfo": false,
            "bDestroy": true,
            "aaData": this.Conditions,
            "aoColumns": this.conditionColumns
        });
    };
}

function InstallmentChanged(period, installment) {
    this.Period = period;
    this.Installment = installment;
}

function LoanMonthly(installment, remainPrinciple, interestAmount, interest, paidPrinciple, payDate, period) {
    this.Installment = installment;
    this.RemainPrinciple = remainPrinciple;
    this.InterestAmount = interestAmount;
    this.Interest = interest;
    this.PaidPrinciple = paidPrinciple;
    this.PayDate = payDate;
    this.Period = period;

}


function to2Digit(num) {
    return parseFloat((Math.round(num * Math.pow(10, 2)) / Math.pow(10, 2)).toFixed(2));
}


function dateReviver(value) {
    var a;
    if (typeof value === 'string') {
        a = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
        if (a) {
            return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
                            +a[5], +a[6]));
        }
    }
    return value;
};
function Summary(totalPeriod, totalPaid, totalPrinciple, totalInterest, payDateStart, payDateEnd, bankName) {
    this.BankName = bankName,
    this.TotalPeriod = totalPeriod;
    this.TotalPeriodText = parseInt(totalPeriod / 12) + " ปี " + totalPeriod % 12 + " เดือน";
    this.TotalPrinciple = totalPrinciple;
    this.TotalInterest = totalInterest;
    this.TotalPaid = totalPaid;
    this.PayDateStart = payDateStart;
    this.PayDateEnd = payDateEnd;
}


function LoanCalculator() {

    this.Loans = [];
    this.SummaryTable = undefined;
    this.Summaries = [];
    this.AddLoan = function (loan) {
        this.Loans.push(loan);
    };
    this.GetLoanByBankName = function (bankName) {
        var loan = $(this.Loans).filter(function (i) {
            return this.BankName == bankName;
        });
        return loan[0];
    };
    this.GetSummaries = function () {
        var sums = [];
        for (var i = 0; i < this.Loans.length; i++) {
            var summary = this.Loans[i].Summary;
            this.Summaries.push(summary);
            sums.push(summary);
        }
        return sums;
    };
    this.onDetailsClick = undefined;
    this.ShowTableChartDetails = function (bankName) {
        var loan = this.GetLoanByBankName(bankName);
        if (currentLoan != loan && loan != undefined) {
            loan.PopulateMonthlyTable();
            loan.PopulateMonthlyChart();
            window.currentLoan = loan;
            jQuery('#Tablemonthlys').goTo();
        }
        if (this.onDetailsClick != undefined) {
            this.onDetailsClick();
        }
    };
    this.SummaryColumn = [

                {
                    "mData": null,  "sWidth": "30", "sTitle": "<input type='checkbox' id='selectAllSummary'></input>", "fnRender": function (o, v) {
                        return '<input type="checkbox" class="summary" name="bankCheck' + o.iDataRow + '" value="' + o.iDataRow + '" />';
                    }
                },
                { "mData": "BankName", "sTitle": "ธนาคาร" },
                { "mData": "TotalPeriodText", "sTitle": "จำนวนงวด" },
                { "mData": "TotalInterest", "sTitle": "ดอกเบี้ยทั้งหมด" },
                { "mData": "TotalPrinciple", "sTitle": "เงินต้นทั้งหมด" },
                { "mData": "TotalPaid", "sTitle": "เงินที่จ่ายทั้งหมด" },
                {
                    "mData": "PayDateStart", "sTitle": "วันที่เริ่มจ่าย", "fnRender": function (oObj) {
                        var javascriptDate = dateReviver(oObj.aData.PayDateStart);
                        javascriptDate = javascriptDate.getDate() + "/" + (javascriptDate.getMonth() + 1) + "/" + javascriptDate.getFullYear();
                        return "<div class= date>" + javascriptDate + "<div>";
                    }
                },
                {
                    "mData": "PayDateEnd", "sTitle": "วันที่จ่ายหมด", "fnRender": function (oObj) {
                        var javascriptDate = dateReviver(oObj.aData.PayDateEnd);
                        javascriptDate = javascriptDate.getDate() + "/" + (javascriptDate.getMonth() + 1) + "/" + javascriptDate.getFullYear();
                        return "<div class= date>" + javascriptDate + "<div>";
                    }
                },
                {
                    "mData": null, "sTitle": "รายละเอียด", "fnRender": function (oObj) {

                        return '<a class="edit" href="javascript: loanCal.ShowTableChartDetails(\'{0}\');">ดูรายละเอียด</a>'.format(oObj.aData.BankName);
                    }
                }
    ];
    this.PopulateSummaryTable = function (datas, DivSummary) {
        
        var _datas = datas;
        var div = DivSummary;
        if (_datas == undefined) {
            _datas = this.GetSummaries();
        }
        if (div == undefined) {
            div = this.SummaryTable;
        }

        this.LoanTable = $('#' + div).dataTable({
            "bPaginate": false,
            "bFilter": false,
            "bInfo": false,
            "bDestroy": true,
            "bProcessing": true,
            "sDom": "<'row'<'span6'l><'span6'f>r>t<'row'<'span6'i><'span6'p>>",
            "sPaginationType": "bootstrap",
            "oLanguage": {
                "sLengthMenu": "_MENU_ records per page"
            },
            "aaData": _datas,
            "bAutoWidth": false,
            "aoColumns": this.SummaryColumn,
            fnPreDrawCallback: function () {
                // Initialize the responsive data table helper once.
                if (!responsiveHelper2 && !destroyingDataTable) {
                    responsiveHelper2 = new ResponsiveDatatablesHelper(this, breakpointDefinition);
                }
            },
            fnRowCallback: function (nRow) {
                if (responsiveHelper2) {
                    responsiveHelper2.createExpandIcon(nRow);
                }
            },
            fnDrawCallback: function () {
                // This function will be called every the table redraws.
                // Specifically, we're interested when next/previous page
                // occurs.
                //toggleMasterCheckBasedOnAllOtherCheckboxes();

                // Respond to windows resize.
                if (responsiveHelper2) {
                    responsiveHelper2.respond();
                }
            },
            fnInitComplete: function (oSettings) {
                // Register event handlers
                //initializeMasterCheckboxEventHandler();
                //initializeCheckboxEventHandlers();
                initializeTableRowEventHandlers(undefined,undefined,this);

                // Unregister event handlers when table is destroyed.
                oSettings.aoDestroyCallback.push({
                    'sName': 'UnregisterEventHandlers',
                    'fn': function () {
                        //initializeMasterCheckboxEventHandler(false);
                        //initializeCheckboxEventHandlers(false);
                        initializeTableRowEventHandlers(false,undefined,this);
                    }
                });
                this.show();
                //this.sWidth = "auto";
            }
        });
    };
    this.PopulateCompareTable = function (datas, DivCompare) {

        var _datas = datas;
        var div = DivCompare;
        if (_datas == undefined) {
            _datas = this.GetSummaries();
        }
        if (div == undefined) {
            div = this.SummaryTable;
        }

        this.LoanTable = $('#' + div).dataTable({
            "bPaginate": false,
            "bFilter": false,
            "bInfo": false,
            "bDestroy": true,
            "sDom": "<'row'<'span6'l><'span6'f>r>t<'row'<'span6'i><'span6'p>>",
            "sPaginationType": "bootstrap",
            "oLanguage": {
                "sLengthMenu": "_MENU_ records per page"
            },
            "aaData": _datas,
            "aoColumns":  [{ "mData": "BankName", "sTitle": "ธนาคาร" },
                            { "mData": "TotalPeriodText", "sTitle": "จำนวนงวด" },
                            { "mData": "TotalInterest", "sTitle": "ดอกเบี้ยทั้งหมด" }]
        });
    };
}

function Loan(divtablename, divChartName, datas) {
    if (datas != undefined) {
        $.extend(this, datas);
    }
    this.BankName = undefined;
    this.LoanConditions = [];
    this.Principle = undefined;
    this.StartDate = undefined;
    this.Installment = undefined;
    this.LoanMonthlys = [];
    this.InstallmentsChanged = [];
    this.divTableDetails = divtablename;
    this.DivchartName = divChartName;
    this._period = 0;
    this._startDate = undefined;
    this.Interest = 5;
    this.LoanTable = undefined;
    this.LoanChart = undefined;
    this.Summary = undefined;
    this.LoanColumns = [

                { "mData": "Period", "sTitle": "งวดที่" },
                {
                    "mData": "Installment", "sTitle": "จ่ายรายเดือน", "sClass": "itm-clm", "fnRender": function (oObj) {
                        return "<a class='installment-edit' href='javascript:void(0)'>{0}</a>".format(oObj.aData.Installment);
                    }
                },
                { "mData": "Interest", "sTitle": "ดอกเบี้ย" },
                //{ "mData": "InterestAmount", "sTitle": "InterestAmount" },
                { "mData": "PaidPrinciple", "sTitle": "เงินต้น" },
                { "mData": "RemainPrinciple", "sTitle": "เงินต้นคงเหลือ" },
                {
                    "mData": "PayDate", "sTitle": "วันที่จ่าย", "fnRender": function (oObj) {
                        var javascriptDate = dateReviver(oObj.aData.PayDate);

                        javascriptDate = javascriptDate.getDate() + "/" + (javascriptDate.getMonth() + 1) + "/" + javascriptDate.getFullYear();
                        return "<div class= date>" + javascriptDate + "<div>";
                    }
                }
    ];
    this.Clear = function () {
        this.LoanMonthlys = [];
        this._period = 0;
    };
    this.Filter = function (periodStart, periodEnd, AutoRefreshTable, ShowSummaryPopup) {
        var filterData = this.LoanMonthlys.filter(function (lm) {
            return lm.Period >= periodStart && lm.Period <= periodEnd;
        });
        if (AutoRefreshTable) {
            this.PopulateMonthlyTable(filterData);
        }
        if (ShowSummaryPopup) {
            var ui = new LoanCalculatorUI();
            var sum = this.ToSummary(filterData);
            ui.notify("Your new Summary", this.GetSummaryContent(sum));
        }
    };
    this.CalStart = function () {
        this._startDate = this.StartDate.clone();
        this.Cal(this.LoanConditions, this.InstallmentsChanged, this.Principle, this._startDate);
    };
    this.ReCalStart = function () {
        this._period = 0;
        this._startDate = this.StartDate.clone();
        this.LoanMonthlys = [];
        this.Cal(this.LoanConditions, this.InstallmentsChanged, this.Principle, this._startDate);
    };

    this.Cal = function (conditions, installmentsChange, tempPrinciple, startDate) {
        while (tempPrinciple > 0) {
            this._period++;
            var interest = this.Interest;
            for (var i = 0; i < conditions.length; i++) {
                if (startDate >= conditions[i].Datefrom && startDate < conditions[i].Dateto) {
                    interest = conditions[i].Interest;
                    break;
                }
            }

            var payMonthly = this.Installment;
            for (var i = 0; i < installmentsChange.length; i++) {
                if (this._period == installmentsChange[i].Period) {
                    payMonthly = installmentsChange[i].Installment;
                    break;
                }
            }

            var mInterest = to2Digit((interest * new Date(startDate.getFullYear(), startDate.getMonth() + 1, 0).getDate() * tempPrinciple) / (100 * 365));
            var principle = to2Digit(payMonthly - mInterest);

            if (tempPrinciple - principle < 0) {
                var ml = new LoanMonthly(to2Digit(tempPrinciple + mInterest), 0, mInterest, mInterest, to2Digit(tempPrinciple), new Date().addMonths(this._period - 1), this._period);
                this.LoanMonthlys.push(ml);
                this.Summary = this.ToSummary(this.LoanMonthlys);
                return 0;
            } else {
                var ml = new LoanMonthly(payMonthly, to2Digit(tempPrinciple - principle), mInterest, mInterest, principle, new Date().addMonths(this._period - 1), this._period);
                this.LoanMonthlys.push(ml);
            }
            var nextMonth = startDate.addMonths(1);
            return this.Cal(conditions, installmentsChange, tempPrinciple - principle, nextMonth);
        }
        return 0;
    };
    this.PopulateMonthlyTable = function (loanMonthlys) {
        var monthlyData = loanMonthlys;
        if (monthlyData == undefined) {
            monthlyData = this.LoanMonthlys;
        }
        this.LoanTable = $('#' + this.divTableDetails).dataTable({
             
            "bPaginate": true,
            "bFilter": false,
            "bInfo": true,
            "bDestroy": true,
            "sDom": "<'row'<'span6'l><'span6'f>r>t<'row'<'span6'i><'span6'p>>",
            "sPaginationType": "bootstrap",
            "oLanguage": {
                "sLengthMenu": "_MENU_ records per page"
            },

            "aaData": monthlyData,
            "aoColumns": this.LoanColumns,
            "bProcessing": true,
            "bAutoWidth": false,
            fnPreDrawCallback: function () {
                // Initialize the responsive data table helper once.
                if (!responsiveHelper && !destroyingDataTable) {
                    responsiveHelper = new ResponsiveDatatablesHelper(this, breakpointDefinition);
                }
            },
            fnRowCallback: function (nRow) {
                if (responsiveHelper) {
                    responsiveHelper.createExpandIcon(nRow);
                }
            },
            fnDrawCallback: function () {
                // This function will be called every the table redraws.
                // Specifically, we're interested when next/previous page
                // occurs.
                //toggleMasterCheckBasedOnAllOtherCheckboxes();

                // Respond to windows resize.
                if (responsiveHelper) {
                    responsiveHelper.respond();
                }
            },
            fnInitComplete: function (oSettings) {
                // Register event handlers
                //initializeMasterCheckboxEventHandler();
                //initializeCheckboxEventHandlers();
                initializeTableRowEventHandlers(undefined,undefined,this);

                // Unregister event handlers when table is destroyed.
                oSettings.aoDestroyCallback.push({
                    'sName': 'UnregisterEventHandlers',
                    'fn': function () {
                        //initializeMasterCheckboxEventHandler(false);
                        //initializeCheckboxEventHandlers(false);
                        initializeTableRowEventHandlers(false,undefined,this);
                    }
                });
                this.show();
            }
        });
    };
    
    this.PopulateMonthlyChart = function (loanMonthlys) {
        var monthlyData = loanMonthlys;
        if (monthlyData == undefined) {
            monthlyData = this.LoanMonthlys;
        }
        var chart;
        chart = new AmCharts.AmSerialChart();
        chart.pathToImages = "/amcharts/images/";
        chart.zoomOutButton = {
            backgroundColor: '#000000',
            backgroundAlpha: 0.15
        };
        chart.dataProvider = monthlyData;
        chart.categoryField = "PayDate";

        // listen for "dataUpdated" event (fired when chart is inited) and call zoomChart method when it happens
        //chart.addListener("dataUpdated", zoomChart);

        // AXES
        // category                
        var categoryAxis = chart.categoryAxis;
        categoryAxis.parseDates = true; // as our data is date-based, we set parseDates to true
        categoryAxis.minPeriod = "DD"; // our data is daily, so we set minPeriod to DD
        categoryAxis.dashLength = 2;
        categoryAxis.gridAlpha = 0.15;
        categoryAxis.axisColor = "#DADADA";

        // first value axis (on the left)
        var valueAxis1 = new AmCharts.ValueAxis();
        valueAxis1.axisColor = "#FF6600";
        valueAxis1.axisThickness = 2;
        valueAxis1.gridAlpha = 0;
        chart.addValueAxis(valueAxis1);

        // second value axis (on the right) 
        //    var valueAxis2 = new AmCharts.ValueAxis();
        //    valueAxis2.position = "right"; // this line makes the axis to appear on the right
        //    valueAxis2.axisColor = "#FCD202";
        //    valueAxis2.gridAlpha = 0;
        //    valueAxis2.axisThickness = 2;
        //    chart.addValueAxis(valueAxis2);

        // third value axis (on the left, detached)
        //    var valueAxis3 = new AmCharts.ValueAxis();
        //    valueAxis3.offset = 50; // this line makes the axis to appear detached from plot area
        //    valueAxis3.gridAlpha = 0;
        //    valueAxis3.axisColor = "#B0DE09";
        //    valueAxis3.axisThickness = 2;
        //    chart.addValueAxis(valueAxis3);

        // GRAPHS
        // first graph
        var graph1 = new AmCharts.AmGraph();
        graph1.valueAxis = valueAxis1; // we have to indicate which value axis should be used
        graph1.title = "ดอกเบี้ย";
        graph1.valueField = "Interest";
        graph1.bullet = "round";
        graph1.hideBulletsCount = 30;
        chart.addGraph(graph1);

        //second graph                
        var graph2 = new AmCharts.AmGraph();
        graph2.valueAxis = valueAxis1; // we have to indicate which value axis should be used
        graph2.title = "เงินต้น";
        graph2.valueField = "PaidPrinciple";
        graph2.bullet = "square";
        graph2.hideBulletsCount = 30;
        chart.addGraph(graph2);

        //    // third graph
        var graph3 = new AmCharts.AmGraph();
        graph3.valueAxis = valueAxis1; // we have to indicate which value axis should be used
        graph3.valueField = "Installment";
        graph3.title = "จ่ายต่อเดือน";
        graph3.bullet = "square";
        graph3.hideBulletsCount = 30;
        chart.addGraph(graph3);

        // CURSOR
        var chartCursor = new AmCharts.ChartCursor();
        chartCursor.cursorPosition = "mouse";
        chart.addChartCursor(chartCursor);

        // SCROLLBAR
        var chartScrollbar = new AmCharts.ChartScrollbar();
        chart.addChartScrollbar(chartScrollbar);

        // LEGEND
        var legend = new AmCharts.AmLegend();
        legend.marginLeft = 110;
        chart.addLegend(legend);

        // WRITE
        chart.write(this.DivchartName);

        //chart.addListener("zoomed", function (data) {
        //    var periodStart = data.startDate;
        //    var periodEnd = data.endDate;

        //    var filterData = [];
        //    jQuery(initialData).each(function (i, d) {
        //        if (new Date(parseInt(d.DateTime.substr(6))) >= periodStart && new Date(parseInt(d.DateTime.substr(6))) <= periodEnd) {
        //            filterData.push(d);
        //        }
        //    });
        //    viewModel.update(filterData);

        //});
    };
    this.ToSummary = function (loanMonthlys) {
        var datas = loanMonthlys;
        if (datas == undefined) {
            datas = this.LoanMonthlys;
        }
        var i = 0;
        var paidTotal = 0;
        var interestTotal = 0;
        var PrincipleTotal = 0;

        for (i = 0; i < datas.length; i++) {
            paidTotal += datas[i].Installment;
            interestTotal += datas[i].Interest;
            PrincipleTotal += datas[i].PaidPrinciple;
        }
        var sum = new Summary(i, to2Digit(paidTotal), to2Digit(PrincipleTotal), to2Digit(interestTotal), datas[0].PayDate, datas[i - 1].PayDate, this.BankName);
        return sum;
    };
    this.GetSummaryContent = function(summary) {
        var _data = typeof summary !== 'undefined' ? summary : this.Summary;

        return "<div><div class='col-lg-6'>ธนาคาร: {0}</div><div class='col-lg-6'>&nbsp;</div></div>".format(_data.BankName) +
            "<div><div class='col-lg-6'>จำนวนงวด: {0}</div><div class='col-lg-6'>จ่ายทั้งหมด: {1}</div></div>".format(_data.TotalPeriodText, _data.TotalPaid) +
            "<div><div class='col-lg-6'>ดอกเบี้ยทั้งหมด: {0}</div><div class='col-lg-6'>เงินต้นทั้งหมด: {1}</div></div>".format(_data.TotalInterest, _data.TotalPrinciple) +
            "<div><div class='col-lg-6'>วันที่เริ่มจ่าย: {0}</div><div class='col-lg-6'>วันที่จ่ายหมด: {1}</div></div>".format(_data.PayDateStart.toDateString(), _data.PayDateEnd.toDateString());
    };

    this.EditInstallment = function (period, inputObj) {
        var installment = $.grep(this.InstallmentsChanged, function (e) { return e.Period == period; });
        if (installment.length > 0) {
            installment[0].Installment = parseInt($(inputObj).val());
        } else {
            this.InstallmentsChanged.push(new InstallmentChanged(period, parseInt($(inputObj).val())));
        }
        this.ReCalStart();
        this.PopulateMonthlyTable();
        this.PopulateMonthlyChart();
        var sum = this.ToSummary(this.LoanMonthlys);
        var ui = new LoanCalculatorUI();
        ui.notify("Your new Summary", this.GetSummaryContent(sum));
    };

    
}

function initializeTableRowEventHandlers(on, elementCollection, table) {
    on = on === undefined ? true : on;

    if (elementCollection === undefined) {
        elementCollection = $(table.fnGetNodes())
    } else if (elementCollection === 'string') {
        elementCollection = $(elementCollection, table.fnGetNodes())
    }

    if (on) {
        // Register elementCollection handlers as needed.
    } else {
        // Unregister elementCollection handlers as needed.
    }
}